package com.wxpay.client.util;

import java.io.IOException;
import java.net.MalformedURLException;
import java.util.HashMap;
import java.util.Map;

import org.apache.http.HttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.util.EntityUtils;

import com.boxin.ims.modules.wechat.utils.HttpClientConnectionManager;
import com.boxin.ims.modules.wechat.utils.XMLUtils;
import com.thinkgem.jeesite.common.mapper.JsonMapper;




public class WxPayHelper {
	
	private HashMap<String, String> parameters = new HashMap<String, String>();
	private String AppId = "";
	private String MchId = "";
	private String ApiKey = "";
	
	public void SetParameter(String key, String value) {
		parameters.put(key, value);
	}

	public String GetParameter(String key) {
		return parameters.get(key);
	}
	
	
	
	public void setAppId(String appId) {
		AppId = appId;
	}


	public void setMchId(String mchId) {
		MchId = mchId;
	}


	public void setApiKey(String apiKey) {
		ApiKey = apiKey;
	}


	/**
	 * post  请求   参数为xml
	 *@author xiaoqian
	 * @param urlStr
	 * @param xmlParam
	 * @return
	 * @throws SDKRuntimeException
	 * 2014-11-11上午10:28:11
	 */
	public String  postXml(String urlStr,String xmlParam) throws SDKRuntimeException{
		 String result = "";
		 
		  DefaultHttpClient httpclient=httpclient = new DefaultHttpClient();
		  httpclient= (DefaultHttpClient) HttpClientConnectionManager.getSSLInstance(httpclient);
			
		try {
//            URL url = new URL(urlStr);
//            URLConnection con = url.openConnection();
//            con.setDoOutput(true);
//            con.setRequestProperty("Pragma:", "no-cache");
//            con.setRequestProperty("Cache-Control", "no-cache");
//            con.setRequestProperty("Content-Type", "text/xml;charset=utf-8");
//
//
//            OutputStreamWriter out = new OutputStreamWriter(con
//                    .getOutputStream());    
//            
//            out.write(new String(xmlParam));
//            out.flush();
//            out.close();
//            BufferedReader br = new BufferedReader(new InputStreamReader(con
//                    .getInputStream()));
//           String line="";
//            for (line = br.readLine(); line != null; line = br.readLine()) {
//////                System.out.println(line);
//            	result+=line;
//            }
			
//            HttpPost httpost = HttpClientConnectionManager.getPostMethod(urlStr);
//			httpost.setEntity(new StringEntity(xmlParam, "UTF-8"));//params  为post请求的
//			httpost.setHeader("Content-Type", "text/xml;charset=utf-8");
//			HttpResponse response = httpclient.execute(httpost);
			
            
			HttpPost post = new HttpPost(urlStr);
			// Construct a string entity
			  StringEntity entity = new StringEntity(xmlParam, "UTF-8");
			  // Set XML entity
			  post.setEntity(entity);
			  // Set content type of request header
			  post.setHeader("Content-Type", "application/xml;");
			// Execute request and get the response
			  HttpResponse response = httpclient.execute(post);
			  String jsonStr = EntityUtils.toString(response.getEntity(), "utf-8");
				System.out.println(jsonStr);
				result=jsonStr;
			
        } catch (MalformedURLException e) {
            e.printStackTrace();
        } catch (IOException e) { 
            e.printStackTrace();
        }
		return result;
	}
	
	
	/**
	 
	 	HashMap<String, String> map = new HashMap<String, String>();
		 map.put("appid", "");//微信分配的公众账号 ID
         map.put("mch_id", "");//微信支付 分配的商户号
         map.put("nonce_str", "");//随机字符串
         map.put("body", "");//商品描述
         map.put("out_trade_no", "");//商户系统内部的订单号
         map.put("total_fee", "");//订单总金额  单位为分
         map.put("spbill_create_ip", "");//订单生成的机器
         map.put("notify_url", "");//接收微信支付成功通知
         map.put("trade_type", "NATIVE");//JSAPI  、  NATIVE   、 APP
         map.put("product_id", "");//只在  trade_type    为      NATIVE 时需要填写。此 id   为二维码 中包含的商品 ID ，商户自行维护。
         map.put("openid", "");//用户在商户   appid  下的唯一  标识，  trade_type    为  JSAPI   时，此参数必传，获取方式   见表头说明。      
         
         //可以不传的
         map.put("device_info", "");//微信支付分配的终端设备号
         map.put("attach", "");//附加数据，原样返回
         map.put("goods_tag", "");//商品标记
         map.put("time_start", "");//订 单 生 成 时 间 ， 格 式 为yyyyMMddHHmmss
         map.put("time_expire", "");//订 单 失 效 时 间， 格 式 为yyyyMMddHHmmss
	 
	 *@author xiaoqian
	 * @param map
	 * @return
	 * 2014-11-11上午10:54:10
	 */
	public String formatParam(HashMap<String, String> map,String key){
		String str= "";
		StringBuffer sb  = new StringBuffer();
		try {
			String param = CommonUtil.FormatBizQueryParaMap(map,false,true);
			
			String sign = MD5SignUtil.Sign(param, key);
			
			
			System.out.println(MD5SignUtil.VerifySignature(param, sign, key));
			
			map.put("sign", sign);
			str = XMLUtils.maptoXml(map);
			
//			sb.append("<xml>");
//			sb.append("\t").append("<sign>"+map.get("sign")+"</sign>").append("\n");
//			sb.append("\t").append("<mch_id>"+map.get("mch_id")+"</mch_id>").append("\n");
//			sb.append("\t").append("<body><![CDATA["+map.get("body")+"]]></body>").append("\n");
//			sb.append("\t").append("<total_fee>"+map.get("total_fee")+"</total_fee>").append("\n");
//			sb.append("\t").append("<spbill_create_ip>"+map.get("spbill_create_ip")+"</spbill_create_ip>").append("\n");
//			sb.append("\t").append("<notify_url>"+map.get("notify_url")+"</notify_url>").append("\n");
//			sb.append("\t").append("<appid>"+map.get("appid")+"</appid>").append("\n");
//			sb.append("\t").append("<openid>"+map.get("openid")+"</openid>").append("\n");
//			sb.append("\t").append("<out_trade_no>"+map.get("out_trade_no")+"</out_trade_no>").append("\n");
//			sb.append("\t").append("<nonce_str>"+map.get("nonce_str")+"</nonce_str>").append("\n");
//			sb.append("\t").append("<trade_type>"+map.get("trade_type")+"</trade_type>").append("\n");
//			sb.append("</xml>");
			
			
			
		} catch (SDKRuntimeException e) {
			e.printStackTrace();
		}
		
		return str;
	}
	
	
	
	/**
	 * 用于Native支付

	 *@author xiaoqian
	 * @param appid
	 * @param key
	 * @param product_id
	 * @param mch_id
	 * @return
	 * @throws SDKRuntimeException
	 * 2014-11-11下午2:04:42
	 */
	public String createPayUrl(String product_id) throws SDKRuntimeException{
		String str ="weixin://wxpay/bizpayurl?";
		String st = CommonUtil.CreateNoncestr();
		
		HashMap<String, String> map = new HashMap<String, String>();
        map.put("appid", AppId);
        map.put("mch_id", MchId);
        map.put("nonce_str", st);
        map.put("product_id",product_id);
        map.put("time_stamp",System.currentTimeMillis()+"");
        
        
        String param = CommonUtil.FormatBizQueryParaMap(map,false,true);
		String sign = MD5SignUtil.Sign(param, ApiKey);
		return str+param+"&sign="+sign;
	}
	
	
	
	/**
	 *  HashMap<String, String> map = new HashMap<String, String>();
		map.put("appid", "wxc5822a0e936601fd");//微信分配的公众账号 ID
        map.put("mch_id", "10019872");//微信支付 分配的商户号
        map.put("nonce_str", str);//随机字符串
        map.put("body", "测试");//商品描述
        map.put("out_trade_no", str);//商户系统内部的订单号
        map.put("total_fee", "1");//订单总金额  单位为分
        map.put("spbill_create_ip", "192.168.1.1");//订单生成的机器
        map.put("notify_url", "http://www.yiyuanzuche.com/");//接收微信支付成功通知
        map.put("trade_type", "JSAPI");//JSAPI  、  NATIVE   、 APP
        map.put("product_id", "1111");//只在  trade_type    为      NATIVE 时需要填写。此 id   为二维码 中包含的商品 ID ，商户自行维护。
        map.put("openid", "");//用户在商户   appid  下的唯一  标识，  trade_type    为  JSAPI   时，此参数必传，获取方式   见表头说明。
	 *@author xiaoqian
	 * @param map1
	 * @param key
	 * @return
	 * @throws Exception 
	 */
	public String createPayUrlByJSAPI() throws Exception{
		String str = CommonUtil.CreateNoncestr();
		
		init(parameters);
        
        String xmlParam = formatParam(parameters, ApiKey);
        System.out.println(xmlParam);
        String result = postXml("https://api.mch.weixin.qq.com/pay/unifiedorder", xmlParam);
        System.out.println("=========================================================");
        System.out.println(result);
        System.out.println("=========================================================");
        Map<String, String> xmlMap =  XMLUtils.xml2Map(result);
        
		HashMap<String, String> map = new HashMap<String, String>();
		 map.put("appId", AppId);//微信分配的公众账号 ID
		 map.put("timeStamp", System.currentTimeMillis()+"");//商品描述
        map.put("nonceStr", str);//随机字符串
        map.put("signType", "MD5");//商户系统内部的订单号
        map.put("package", "prepay_id="+xmlMap.get("xml.prepay_id"));//订单总金额  单位为分
        
        String param = CommonUtil.FormatBizQueryParaMap(map,false,false);
		String sign = MD5SignUtil.Sign(param, ApiKey);
		
		System.out.println(param);
		
		map.put("paySign", sign);
		
		return JsonMapper.getInstance().toJson(map);
	}
	
	/**
	 * 根据商家订单号查找支付订单是否交易成功
	 * @return
	 * @throws Exception
	 */
	public Map<String, String> findPayUrlByJSAPI() throws Exception{
		init(parameters);
        String xmlParam = formatParam(parameters, ApiKey);
        System.out.println(xmlParam);
        String result = postXml("https://api.mch.weixin.qq.com/pay/orderquery", xmlParam);
        Map<String, String> xmlMap =  XMLUtils.xml2Map(result);
        
        Map<String,String> params =  new HashMap<String, String>();
        
        params.put("return_code", xmlMap.get("xml.return_code"));//请求是否成功
        params.put("return_msg", xmlMap.get("xml.return_msg"));//请求描述
        params.put("result_code", xmlMap.get("xml.result_code"));//交易是否成功
        
        params.put("trade_state", xmlMap.get("xml.trade_state"));//交易状态码【SUCCESS—支付成功，REFUND—转入退款，NOTPAY—未支付，CLOSED—已关闭，REVOKED—已撤销（刷卡支付），USERPAYING--用户支付中，PAYERROR--支付失败(其他原因，如银行返回失败)】
        params.put("transaction_id", xmlMap.get("xml.transaction_id"));//交易成功的微信支付单号
        
        params.put("err_code", xmlMap.get("xml.err_code"));//交易失败后的交易码
        params.put("err_code_des", xmlMap.get("xml.err_code_des"));//交易失败后的描述
        params.put("total_fee", xmlMap.get("xml.total_fee"));//交易失败后的描述
        
		return params;
	}
	
	
	/**
	 * 传入参数
	 *@author xiaoqian
	 * @param parameters
	 * 2014-11-11下午5:07:25
	 */
	public void init( HashMap<String, String> parameters ){
		parameters.put("appid", AppId);
		parameters.put("mch_id", MchId);
	}
	
	public String getPayUrl() throws Exception{
		
		init(parameters);
		
		String test ="\n\n<xml>\n   <sign>0B382B4032AEC52C8F6F44F77612845D</sign>\n   <mch_id>10019872</mch_id>\n   <body>苹果</body>\n   <spbill_create_ip>192.168.1.119</spbill_create_ip>\n   <total_fee>1</total_fee>\n   <notify_url>http://xiao501849930.vicp.cc/zxims/f/site/shopping/wxNotify</notify_url>\n   <appid>wxc5822a0e936601fd</appid>\n   <openid>opGpjuKgC11nzeQlDJ82AplGSyZ8</openid>\n   <out_trade_no>1514120141114090342</out_trade_no>\n   <nonce_str>WhGx0vhJHPyaDiyj</nonce_str>\n   <trade_type>JSAPI</trade_type>\n</xml>\n";
		
     	 String xmlParam = formatParam(parameters, ApiKey);
        String result = postXml("https://api.mch.weixin.qq.com/pay/unifiedorder", test);
        
        Map<String, String> map =  XMLUtils.xml2Map(result);
        
		
		return map.get("xml.code_url");
	}
	
	public static void main(String[] args) throws Exception {
		
		String str = CommonUtil.CreateNoncestr();
		
		WxPayHelper helper = new WxPayHelper();
//		helper.setApiKey("yiyuanwang163eyuanwanghujaeifdel");
//		helper.setAppId("wxc5822a0e936601fd");
//		helper.setMchId("10019872");
//		helper.SetParameter("nonce_str", str);
//		helper.SetParameter("body", "你哈");
//		helper.SetParameter("out_trade_no", str);
//		helper.SetParameter("total_fee", "1");
//		helper.SetParameter("spbill_create_ip", "192.168.1.1");
//		helper.SetParameter("notify_url", "http://xiao501849930.vicp.cc/zxims/f/site/shopping/test");
//		helper.SetParameter("trade_type", "JSAPI");
//		helper.SetParameter("openid", "opGpjuKgC11nzeQlDJ82AplGSyZ8");
		
		
		helper.setApiKey("ziqishangmao666888ziqishangmao88");
		helper.setAppId("wxb3a3f3ff6d065705");
		helper.setMchId("10028663");
		helper.SetParameter("nonce_str", "EG3zGVX1rQuukoVo");
		helper.SetParameter("body", "苹果");
		helper.SetParameter("out_trade_no", "24900201412021014934");
		helper.SetParameter("total_fee", "1");
		helper.SetParameter("spbill_create_ip", "192.168.1.119");
		helper.SetParameter("notify_url", "http://weixin.zhaotang.net/zt/f/site/shopping/wxNotify");
		helper.SetParameter("trade_type", "JSAPI");
		helper.SetParameter("openid", "oVnWcjpyiZgPcVpCAbXSXOR3ncXA");
		
		System.out.println(helper.createPayUrlByJSAPI());
		
		
//		String str1 = "\n\n<xml>\n   <sign>0B382B4032AEC52C8F6F44F77612845D</sign>\n   <mch_id>10019872</mch_id>\n   <body>苹果</body>\n   <spbill_create_ip>192.168.1.119</spbill_create_ip>\n   <total_fee>1</total_fee>\n   <notify_url>http://xiao501849930.vicp.cc/zxims/f/site/shopping/wxNotify</notify_url>\n   <appid>wxc5822a0e936601fd</appid>\n   <openid>opGpjuKgC11nzeQlDJ82AplGSyZ8</openid>\n   <out_trade_no>1514120141114090342</out_trade_no>\n   <nonce_str>WhGx0vhJHPyaDiyj</nonce_str>\n   <trade_type>JSAPI</trade_type>\n</xml>\n";
//		
//		
//		
//		
//		String result = helper.postXml("https://api.mch.weixin.qq.com/pay/unifiedorder", str1);
		
		
//		Map<String, String> xmlMap =  XMLUtils.xml2Map("<xml><appid><![CDATA[wxc5822a0e936601fd]]></appid><bank_type><![CDATA[CITIC_DEBIT]]></bank_type><fee_type><![CDATA[CNY]]></fee_type><is_subscribe><![CDATA[Y]]></is_subscribe><mch_id><![CDATA[10019872]]></mch_id><nonce_str><![CDATA[HNvv7C5ceWKFFpmR]]></nonce_str><openid><![CDATA[opGpjuKgC11nzeQlDJ82AplGSyZ8]]></openid><out_trade_no><![CDATA[15141201411140903411]]></out_trade_no><result_code><![CDATA[SUCCESS]]></result_code><return_code><![CDATA[SUCCESS]]></return_code><sign><![CDATA[8BB824844D2667DA67C0D42E5C4A1A84]]></sign><sub_mch_id><![CDATA[10019872]]></sub_mch_id><time_end><![CDATA[20141124120720]]></time_end><total_fee>1</total_fee><trade_type><![CDATA[JSAPI]]></trade_type><transaction_id><![CDATA[1003520032201411240006160341]]></transaction_id></xml>");
//		System.out.println(xmlMap.get("xml.transaction_id"));
		
		
		/*helper.setAppId("wx31517e96ca4d0f53");
		helper.setMchId("1225407002");
		helper.setApiKey("zxdkfncbc728194jfkdmcvfklooed8ew");
		helper.SetParameter("out_trade_no", "29213720151030234");
		helper.SetParameter("nonce_str", str);
		
		System.out.println(helper.findPayUrlByJSAPI());*/
		
	}
	
	
	
}
